#pragma once
#include "base/function.h"
#include "MyRpc/rpccall.hpp"

#include <vector>

namespace myrpc::base
{

  class Rpc
  {
  public:
    Rpc();
    ~Rpc() = default;
    template <typename T>
    void Init_fun(
        uint32_t type, T &&func_body, rpc_callback &&cb = [](net_tools::net::Connect *, void *, unsigned int)
                                      { ; })
    {
      if (Rpc_type_is_available(type))
      {
        rpc_vec_[type].Init(typename detail::Traits_Ret_Arg<typename std::decay<T>::type>::Ret_Args(),
                            static_cast<typename detail::Traits_Ret_Arg<typename std::decay<T>::type>::T>(func_body),
                            std::forward<rpc_callback>(cb));
      }
    };
    unsigned int Call_fun(net_tools::net::Connect *connect, char *buf);
    uint32_t Analyze_uint(char *buf) const;
    static bool Rpc_type_is_available(uint32_t type)
    {
      return type <= rpc_type_size_;
    };

  private:
    std::vector<Rpccall<>> rpc_vec_;
    const uint32_t head_size_ = sizeof(uint32_t);
    const uint32_t len_size_ = sizeof(uint32_t);
    static const uint32_t rpc_type_size_ = 3;
  };

} // namespace myrpc::base